package org.person.gift.listener;



import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.person.gift.constants.OrderConstant;
import org.person.gift.service.IOrderGiftService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 订单超时取消的延迟消息监听
 * 收到延迟消息以后,要做什么事情??
 *   判断当前订单是否支付??  不管该订单支没支付,延迟消息到了30分钟以后,都要触发的
 *   如果已经支付,就不对该订单做处理
 *   如果没有支付,才对订单做处理??
 *       将订单的状态,修改为 超时取消  -  订单服务
 *       将锁定库存,释放   -  礼物服务
 *       将支付单的状态,修改为 已取消  - 支付服务
 *       如果是从购物车下订单的商品,无需回滚
 *
 *  怎么实现??
 *     下订单时,要发送一个延迟消息
 *     监听延迟消息,后续处理??
 *         方案一: 发送事务消息,保证分布式事务一致性
 *              订单服务里面,监听到延迟消息的topic以后:
 *                  根据订单号查询订单状态,如果订单状态=未支付,才发送事务消息
 *              在本地事务中执行:
 *                  修改订单的状态=取消,并返回commit
 *              礼物服务:监听事务消息,拿到消息以后,将对应sku的锁定库存释放
 *              支付服务:根据订单号查询支付单,并修改支付单的状态
 *         方案二: 各个业务微服务,直接监听延迟消息的topic,各个业务微服务单独做处理
 *              订单服务: 根据订单号判断状态,如果未支付,则取消订单
 *              礼物服务: 根据订单号获取订单的信息,判断状态,如果未支付,则取消订单
 *              支付服务: 根据订单号查询支付单的状态,如果未支付,则取消支付单
 *         方案三: seata - 2pc,拿到消息以后,如果订单未支付,才进行后续处理,对于未支付订单而言,并发其实也不是很高
 */
@Component
@RocketMQMessageListener(topic = OrderConstant.PLACE_ORDER_TIMEOUT_CANCEL_TOPIC,
                        consumerGroup = OrderConstant.PLACE_ORDER_TIMEOUT_CANCEL_CONSUMER_GROUP)
public class OrderTimeOutCancelDelayMessageListener implements RocketMQListener<MessageExt> {

    @Autowired
    private IOrderGiftService orderGiftService;

    @Override
    public void onMessage(MessageExt message) {
        // 获取消息
        byte[] body = message.getBody();
        String parentOrderNo = new String(body);

        // 取消订单
        orderGiftService.cancelOrder(parentOrderNo);
    }
}
